﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Locator.Silverlight.Client.Models.StoresServiceReference;
using System.Collections.ObjectModel;
using Locator.Silverlight.Client.Models.ViewModels.Screens;
using Locator.Silverlight.Client.Models;
using Locator.Silverlight.Client.Models.ViewModels.Elements;

namespace Locator.Silverlight.Client.Test
{
    [TestClass]
    public class ManageStoresViewModelTests
    {
        private static MockStoreService BuildStoreService()
        {
            MockStoreService storeService = new MockStoreService()
            {
                GetStoresForCurrentUserResult = new ObservableCollection<Store>
                {
                    new Store()
                    {
                        Address = "123 Fake St.",
                        City = "Springfield",
                        Id = 1,
                        Latitude = 43.0M,
                        Longitude = -79.0M
                    }
                },

                AllCitiesResult = new ObservableCollection<string>
                {
                    "Springfield",
                    "Shelbyville",
                    "North Haverbrook",
                    "Ogdenville"
                },

                GetPersonalLocationsForCurrentUserResult = new ObservableCollection<PersonalLocation>
                {
                    new PersonalLocation()
                    {
                            Description="Home",
                            Id = 1,
                            Latitude = 42.0M,
                            Longitude = -78.0M
                    }
                },

                FindStoresInCityResult = new ObservableCollection<Store>
                {
                    new Store()
                    {
                        Address = "123 Fake St.",
                        City = "Springfield",
                        Id = 1,
                        Latitude = 43.0M,
                        Longitude = -79.0M
                    }
                },

                FindStoresByPostalCodeResult = new ObservableCollection<Store>
                {
                    new Store()
                    {
                        Address = "742 Evergreen Tr.",
                        City = "Springfield",
                        Id = 2,
                        Latitude = 42.0M,
                        Longitude = -80.0M
                    }
                },

                FindStoresByPersonalLocationResult = new ObservableCollection<Store>
                {
                    new Store()
                    {
                        Address = "Moe's Tavern",
                        City = "Springfield",
                        Id = 3,
                        Latitude = 41.0M,
                        Longitude = -81.0M
                    }
                },

                FindStoresByLatitudeAndLongitudeResult = new ObservableCollection<Store>
                {
                    new Store()
                    {
                        Address = "Mr Burns' House",
                        City = "Springfield",
                        Id = 4,
                        Latitude = 40.0M,
                        Longitude = -82.0M
                    }
                }
            };

            return storeService;
        }

        [TestMethod]
        public void InitViewModelTest()
        {
            MockStoreService storeService = BuildStoreService();

            using (ManageStoresViewModel viewModel = new ManageStoresViewModel(new StoreModel(storeService)))
            {
                Assert.AreEqual(4, viewModel.AllCities.Count);
                Assert.AreEqual("Springfield", viewModel.AllCities[0].Name);

                Assert.AreEqual(1, viewModel.PersonalLocations.Count);
                Assert.AreEqual("Home", viewModel.PersonalLocations[0].Description);
                Assert.AreEqual(42.0M, viewModel.PersonalLocations[0].Latitude);
                Assert.AreEqual(-78.0M, viewModel.PersonalLocations[0].Longitude);
                Assert.AreEqual(1, viewModel.PersonalLocations[0].Id);

                Assert.AreEqual(1, viewModel.UserStores.Count);
                Assert.AreEqual("123 Fake St., Springfield", viewModel.UserStores[0].Address);
                Assert.AreEqual(1, viewModel.UserStores[0].Id);
                Assert.AreEqual(43.0M, viewModel.UserStores[0].Latitude);
                Assert.AreEqual(-79.0M, viewModel.UserStores[0].Longitude);

                Assert.AreEqual(5, viewModel.SearchRadiusItems.Count);
                Assert.AreEqual(5, viewModel.SearchRadiusItems[0]);
                Assert.AreEqual(10, viewModel.SearchRadiusItems[1]);
                Assert.AreEqual(15, viewModel.SearchRadiusItems[2]);
                Assert.AreEqual(20, viewModel.SearchRadiusItems[3]);
                Assert.AreEqual(2000, viewModel.SearchRadiusItems[4]);
                Assert.AreEqual(5, viewModel.SearchRadius);
            }
        }

        [TestMethod]
        public void SearchByCityTest()
        {
            MockStoreService storeService = BuildStoreService();
            using (ManageStoresViewModel viewModel = new ManageStoresViewModel(new StoreModel(storeService)))
            {
                viewModel.FindStoresCommand.Execute(viewModel.AllCities[0].Name);
                Assert.AreEqual(1, viewModel.SearchResults.Count);

                Assert.AreEqual(1, viewModel.SearchResults[0].Store.Id);
                Assert.AreEqual("123 Fake St., Springfield", viewModel.SearchResults[0].Store.Address);
                Assert.AreEqual(43.0M, viewModel.SearchResults[0].Store.Latitude);
                Assert.AreEqual(-79.0M, viewModel.SearchResults[0].Store.Longitude);
                Assert.IsTrue(viewModel.SearchResults[0].UsedByUser);
            }
        }

        [TestMethod]
        public void SearchByPostalCodeTest()
        {
            MockStoreService storeService = BuildStoreService();
            using (ManageStoresViewModel viewModel = new ManageStoresViewModel(new StoreModel(storeService)))
            {
                viewModel.PostalCode = "L6H 6J1";
                viewModel.FindStoresByPostalCodeCommand.Execute(null);
                Assert.AreEqual(1, viewModel.SearchResults.Count);

                Assert.AreEqual(2, viewModel.SearchResults[0].Store.Id);
                Assert.AreEqual("742 Evergreen Tr., Springfield", viewModel.SearchResults[0].Store.Address);
                Assert.AreEqual(42.0M, viewModel.SearchResults[0].Store.Latitude);
                Assert.AreEqual(-80.0M, viewModel.SearchResults[0].Store.Longitude);
                Assert.IsFalse(viewModel.SearchResults[0].UsedByUser);
                Assert.AreEqual(viewModel.SearchRadius, storeService.RadiusSearched);
            }
        }

        [TestMethod]
        public void SearchByPersonalLocationTest()
        {
            MockStoreService storeService = BuildStoreService();
            using (ManageStoresViewModel viewModel = new ManageStoresViewModel(new StoreModel(storeService)))
            {
                
                viewModel.FindStoresByPersonalLocationCommand.Execute(viewModel.PersonalLocations[0]);
                Assert.AreEqual(1, viewModel.SearchResults.Count);

                Assert.AreEqual(4, viewModel.SearchResults[0].Store.Id);
                Assert.AreEqual("Mr Burns' House, Springfield", viewModel.SearchResults[0].Store.Address);
                Assert.AreEqual(40.0M, viewModel.SearchResults[0].Store.Latitude);
                Assert.AreEqual(-82.0M, viewModel.SearchResults[0].Store.Longitude);
                Assert.IsFalse(viewModel.SearchResults[0].UsedByUser);
                Assert.AreEqual(viewModel.SearchRadius, storeService.RadiusSearched);
            }
        }

        [TestMethod]
        public void AddStoreTest()
        {
            MockStoreService storeService = BuildStoreService();
            using (ManageStoresViewModel viewModel = new ManageStoresViewModel(new StoreModel(storeService)))
            {
                viewModel.SearchResults = new ObservableCollection<Models.ViewModels.Elements.UserStoreViewModel>
                {
                    new UserStoreViewModel(
                        new StoreViewModel()
                        {
                            Id = 10
                        }
                    )
                    {
                        UsedByUser = false
                    }
                };

                Assert.AreEqual(1, viewModel.UserStores.Count);
                viewModel.AddStoreCommand.Execute(viewModel.SearchResults[0]);
                Assert.IsTrue(storeService.AddCalled);
                Assert.AreEqual(2, viewModel.UserStores.Count);
                Assert.IsTrue(viewModel.SearchResults[0].UsedByUser);
                Assert.AreEqual(10, viewModel.UserStores[1].Id);
            }
        }

        [TestMethod]
        public void DeleteStoreTest()
        {
            MockStoreService storeService = BuildStoreService();
            using (ManageStoresViewModel viewModel = new ManageStoresViewModel(new StoreModel(storeService)))
            {
                Assert.AreEqual(1, viewModel.UserStores.Count);
                viewModel.RemoveStoreCommand.Execute(viewModel.UserStores[0]);
                Assert.IsTrue(storeService.DeleteCalled);
                Assert.AreEqual(0, viewModel.UserStores.Count);
            }
        }
    }
}
